home *** CD-ROM | disk | FTP | other *** search
-
- CONST
- { Video RAM plane color segments : blue, red, green }
- sgment : ARRAY [0..2] OF INTEGER = ( $C000,$D000,$E000 ) ;
- color_name : ARRAY [0..7] OF string[7] =
- ('BLACK ','BLUE ','RED ','MAGENTA','GREEN ',
- 'CYAN ','YELLOW ','WHITE ');
-
- black = 0; { Pixel colors }
- blue = 1;
- red = 2;
- magenta = 3;
- green = 4;
- cyan = 5;
- yellow = 6;
- white = 7 ;
- vcr = $D8; { Video control register }
-
- VAR
- old_vcr : integer;
- aspect : array[0..225] of integer;
- current_ratio : real;
-
- {
- The following routine MUST be called before any use of the graphics
- routines included in this module. It enables the video port for
- graphics output and also sets up the aspect ratio table for circle
- plotting.
- }
-
- PROCEDURE graphon;
- var
- i : integer;
- BEGIN
- ClrScr;
- old_vcr := port[vcr];
- port[vcr] := old_vcr and $7F;
- for i := 0 to 225 do
- aspect[i] := round(i * 0.4843);
- current_ratio := 1.0;
- END;
-
- PROCEDURE graphoff;
- BEGIN
- port[vcr] := old_vcr;
- ClrScr;
- END;
-
- { Returns address of X,Y pixel location }
- FUNCTION byteaddr (x,y:integer) : integer;
- VAR
- xbyte,ychar,yscan : integer;
- BEGIN
- xbyte := x DIV 8;
- ychar := y DIV 9;
- yscan := y MOD 9;
- byteaddr := ychar*2048 + yscan*128 + xbyte;
- END;
-
- { PSET: turns on a pixel of color COLOR }
- PROCEDURE pset (x,y,color : integer);
- VAR
- bit_off,location,xbit,plane : integer;
- vidchr : ^byte;
- BEGIN
- location := byteaddr (x,y);
- xbit := $80 SHR (x MOD 8);
- bit_off:=NOT xbit;
- FOR plane := 0 TO 2 DO BEGIN
- vidchr := ptr(sgment[plane],location);
- if (color and (1 shl plane) > 0) then
- vidchr^ := vidchr^ OR xbit
- ELSE
- vidchr^ := vidchr^ AND bit_off;
- END;
- END;
-
- { PRESET: turns off a pixel at x,y }
- PROCEDURE preset (x,y : integer);
- VAR
- bit_off,location,xbit,plane : integer;
- BEGIN
- location := byteaddr (x,y);
- xbit := $80 SHR (x MOD 8);
- bit_off:=NOT xbit;
- FOR plane := 0 TO 2 DO
- mem[sgment[plane]:location] := mem[sgment[plane]:location] AND bit_off;
- END;
-
- { DRAWLINE: draws a line from pixel ix1,iy1 to pixel ix2,iy2 of COLOR }
- procedure drawline(ix1,iy1,ix2,iy2,color : integer);
- var
- dev, dx, dy, x, y : integer;
-
- procedure case1;
- begin
- for x := (ix1 + 1) to ix2 do begin
- dev := dev + dy + dy;
- if dev > dx then begin
- y := y + 1;
- dev := dev - dx - dx
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case2;
- begin
- for y := (iy1 + 1) to iy2 do begin
- dev := dev + dx + dx;
- if dev > dy then begin
- x := x + 1;
- dev := dev - dy - dy;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case3;
- begin
- for x := (ix1 + 1) to ix2 do begin
- dev := dev + dy + dy;
- if dev > dx then begin
- y := y - 1;
- dev := dev - dx - dx;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case4;
- begin
- for y := (iy1 - 1) downto iy2 do begin
- dev := dev + dx + dx;
- if dev > dy then begin
- x := x + 1;
- dev := dev - dy - dy;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case5;
- begin
- for x := (ix1 - 1) downto ix2 do begin
- dev := dev + dy + dy;
- if dev > dx then begin
- y := y + 1;
- dev := dev - dx - dx;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case6;
- begin
- for y := (iy1 + 1) to iy2 do begin
- dev := dev + dx + dx;
- if dev > dy then begin
- x := x - 1;
- dev := dev - dy - dy;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case7;
- begin
- for x := (ix1 - 1) downto ix2 do begin
- dev := dev + dy + dy;
- if dev > dx then begin
- y := y - 1;
- dev := dev - dx - dx;
- end;
- pset(x,y,color);
- end;
- end;
-
- procedure case8;
- begin
- for y := (iy1 - 1) downto iy2 do begin
- dev := dev + dx + dx;
- if dev > dy then begin
- x := x - 1;
- dev := dev - dy - dy;
- end;
- pset(x,y,color);
- end;
- end;
-
- begin {drawline}
- if ix1 = ix2 then
- if iy1 < iy2 then
- for y := iy1 to iy2 do
- pset(ix1,y,color)
- else
- for y := iy1 downto iy2 do
- pset(ix1,y,color)
- else if iy1 = iy2 then
- if ix1 < ix2 then
- for x := ix1 to ix2 do
- pset(x,iy1,color)
- else
- for x := ix1 downto ix2 do
- pset(x,iy1,color)
- else begin
- pset(ix1,iy1,color);
- dev := 0;
- x := ix1; y := iy1;
- dx := abs(ix2 - ix1);
- dy := abs(iy2 - iy1);
- if ix2 >= ix1 then
- if iy2 >= iy1 then
- if dx >= dy then case1 else case2
- else
- if dx >= dy then case3 else case4
- else
- if iy2 >= iy1 then
- if dx >= dy then case5 else case6
- else
- if dx >= dy then case7 else case8;
- end;
- end;
-
- { DRAWBOX: draws a rectangle whose upper left corner is at x1,y1
- and whose lower right corner is at x2,y2 }
- procedure drawbox(x1,y1,x2,y2,color : integer);
- begin
- drawline(x1,y1,x2,y1,color);
- drawline(x2,y1,x2,y2,color);
- drawline(x2,y2,x1,y2,color);
- drawline(x1,y2,x1,y1,color);
- end;
-
- { DRAWCIRCLE: draws an elipse centered at ix,iy of radius ir (in x pixels)
- of 'color'. ratio is 1.0 for a circle...greater than 1.0
- for a vertical elipse and less than 1.0 for a horizontal
- elipse. }
- procedure drawcircle(ix,iy,ir,color : integer; ratio : real);
- var
- x,y,dev : integer;
- ta : array[0..225] of integer;
- i : integer;
-
- procedure reflect;
- begin
- pset(ix+x,iy+aspect[y],color);
- pset(ix-x,iy+aspect[y],color);
- pset(ix+x,iy-aspect[y],color);
- pset(ix-x,iy-aspect[y],color);
- if x <> y then begin
- pset(ix+y,iy+aspect[x],color);
- pset(ix-y,iy+aspect[x],color);
- pset(ix+y,iy-aspect[x],color);
- pset(ix-y,iy-aspect[x],color);
- end
- end;
-
- begin {drawcircle}
- if ratio <> current_ratio then begin
- for i := 0 to 225 do
- aspect[i] := round(i * (0.4843 * ratio));
- current_ratio := ratio;
- end;
- x := ir;
- y := 0;
- dev := 0;
- pset(ix+ir,iy,color);
- pset(ix,iy+aspect[ir],color);
- pset(ix-ir,iy,color);
- pset(ix,iy-aspect[ir],color);
- while y < x do begin
- dev := dev + y + y + 1;
- y := y + 1;
- if dev > x then begin
- dev := dev - x - x + 1;
- x := x - 1;
- end;
- reflect;
- end
- end;